package com.ruoyi.recycleshop.listener;

import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSON;
import com.ruoyi.recycle.domain.Coupon;
import com.ruoyi.recycleshop.event.CreateCouponEvent;
import com.ruoyi.recycleshop.event.DeleteCouponEvent;
import com.ruoyi.recycleshop.event.ModifyCouponEvent;
import com.ruoyi.recycleshop.job.CreateCouponJob;
import lombok.RequiredArgsConstructor;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.quartz.*;
import org.springframework.context.event.EventListener;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.Date;

@RequiredArgsConstructor
@Component
@Slf4j
public class CouponListener {
    @Resource(name = "scheduler")
    private final Scheduler scheduler;

    @Async
    @EventListener({CreateCouponEvent.class})
    @SneakyThrows
    public void createCoupon(CreateCouponEvent coupon) {
        Coupon source = (Coupon) coupon.getSource();
        final String id = String.valueOf(source.getId());
        final JobDataMap dataMap = new JobDataMap();
        final Date effectStart = source.getEffectStart();
        final Date effectEnd = source.getEffectEnd();
        final Date current = new Date();
        final int compare = current.compareTo(effectEnd);
        if (compare > 0) {
            final JobDataMap invalidDataMap = new JobDataMap();
            invalidDataMap.put("create_coupon", JSON.toJSONString(source));
            invalidDataMap.put("isExpire", true);
            final JobDetail invalidJobDetail = JobBuilder.newJob(CreateCouponJob.class).usingJobData(invalidDataMap).withIdentity(id).build();
            final SimpleTrigger invalidTrigger = TriggerBuilder.newTrigger()
                    .startAt(new Date())
                    .withIdentity(id)
                    .withSchedule(SimpleScheduleBuilder.simpleSchedule()).build();
            scheduler.scheduleJob(invalidJobDetail, invalidTrigger);
        } else {
            dataMap.put("create_coupon", JSON.toJSONString(source));
            dataMap.put("isExpire", false);
            final JobDetail jobDetail = JobBuilder.newJob(CreateCouponJob.class).usingJobData(dataMap).withIdentity(id).build();
            final SimpleTrigger trigger = TriggerBuilder.newTrigger()
                    .startAt(current.compareTo(effectStart) >= 0 ? effectStart : new Date())
                    .withIdentity(id)
                    .withSchedule(SimpleScheduleBuilder.simpleSchedule()).build();
            final JobDataMap expireJobMap = new JobDataMap();
            expireJobMap.put("create_coupon", JSON.toJSONString(source));
            expireJobMap.put("isExpire", true);
            final JobDetail expireJobDetail = JobBuilder.newJob(CreateCouponJob.class).usingJobData(expireJobMap).withIdentity(id + "End").build();
            final SimpleTrigger expireTrigger = TriggerBuilder.newTrigger()
                    .startAt(DateUtil.offsetSecond(effectEnd, 1).toJdkDate())
                    .withIdentity(id + "End")
                    .withSchedule(SimpleScheduleBuilder.simpleSchedule())
                    .build();
            scheduler.scheduleJob(jobDetail, trigger);
            scheduler.scheduleJob(expireJobDetail, expireTrigger);
        }

        if (!scheduler.isShutdown()) {
            scheduler.start();
            log.info("设置优惠券有效期任务启动,优惠券ID为:{}", id);
        }

    }

    @Async
    @EventListener({ModifyCouponEvent.class})
    @SneakyThrows
    public void modifyCoupon(ModifyCouponEvent coupon) {
        final Coupon source = (Coupon) coupon.getSource();
        final String id = String.valueOf(source.getId());
        scheduler.deleteJob(new JobKey(id, null));
        scheduler.deleteJob(new JobKey(id + "End", null));
        final JobDataMap dataMap = new JobDataMap();
        dataMap.put("create_coupon", JSON.toJSONString(source));
        dataMap.put("isExpire", false);
        final String couponNo = source.getCouponName();
        final JobDetail jobDetail = JobBuilder.newJob(CreateCouponJob.class).usingJobData(dataMap).withIdentity(id).build();
        final SimpleTrigger trigger = TriggerBuilder.newTrigger()
                .startAt(source.getEffectStart())
                .withIdentity(id)
                .withSchedule(SimpleScheduleBuilder.simpleSchedule()).build();
        final JobDataMap expireJobMap = new JobDataMap();
        expireJobMap.put("create_coupon", JSON.toJSONString(source));
        expireJobMap.put("isExpire", true);
        final JobDetail expireJobDetail = JobBuilder.newJob(CreateCouponJob.class).usingJobData(expireJobMap).withIdentity(id + "End").build();
        final SimpleTrigger expireTrigger = TriggerBuilder.newTrigger()
                .startAt(source.getEffectEnd())
                .withIdentity(id + "End")
                .withSchedule(SimpleScheduleBuilder.simpleSchedule())
                .build();
        scheduler.scheduleJob(jobDetail, trigger);
        scheduler.scheduleJob(expireJobDetail, expireTrigger);
        if (!scheduler.isShutdown()) {
            scheduler.start();
            log.info("修改优惠券有效期任务启动,优惠券号为:{}", couponNo);
        }
    }

    @Async
    @EventListener({DeleteCouponEvent.class})
    @SneakyThrows
    public void deleteCoupon(DeleteCouponEvent id) {
        final String jobId = (String) id.getSource();
        scheduler.deleteJob(new JobKey(jobId, null));
        scheduler.deleteJob(new JobKey(jobId + "End", null));
    }
}
